package com.tencreat.account.controller.app;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.cglib.CglibUtil;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.IPage;
import com.tencreat.common.annotation.Log;
import com.tencreat.common.annotation.RepeatSubmit;
import com.tencreat.common.constant.HttpStatus;
import com.tencreat.common.constant.TencreatIdAndName;
import com.tencreat.common.core.HttpResult;
import com.tencreat.common.core.controller.BaseController;
import com.tencreat.common.core.domain.entity.SysUser;
import com.tencreat.common.core.domain.model.*;
import com.tencreat.common.core.domain.model.LoginUser;
import com.tencreat.common.core.service.TokenService;
import com.tencreat.common.enums.BusinessType;
import com.tencreat.common.enums.OrderStatus;
import com.tencreat.common.enums.account.CitySmsTypeEnum;
import com.tencreat.common.enums.mall.AllEnum;
import com.tencreat.common.exception.CustomException;
import com.tencreat.common.utils.SecurityUtils;
import com.tencreat.common.utils.bean.BeanUtils;
import com.tencreat.common.utils.StringUtils;
import com.tencreat.common.utils.VerifyUtil;
import com.tencreat.domain.account.*;
import com.tencreat.domain.account.dto.*;
import com.tencreat.domain.account.vo.AccountMyTeamVo;
import com.tencreat.domain.account.vo.ResAccountLogin;
import com.tencreat.domain.account.vo.ResOpenUserInfoVO;
import com.tencreat.domain.account.dto.AccountOpenSupplierSettleInDTO;
import com.tencreat.domain.account.dto.UpdateNewPhoneDTO;
import com.tencreat.domain.account.dto.AccountLoginDTO;
import com.tencreat.domain.account.dto.AccountPhoneAndCodeDTO;
import com.tencreat.domain.account.dto.AccountRegisterDTO;
import com.tencreat.domain.account.dto.ShopOpenSendCodeDTO;
import com.tencreat.domain.account.vo.AppMyTeamInfoVO;
import com.tencreat.domain.im.ImCustomer;
import com.tencreat.domain.mall.AppDownloadRecord;
import com.tencreat.domain.mall.MallMessageRecord;
import com.tencreat.domain.mall.MallOrder;
import com.tencreat.domain.mall.MallOrderGoods;
import com.tencreat.domain.mall.vo.MallOrderStatisticsVO;
import com.tencreat.domain.im.dto.OpenIMLoginDTO;
import com.tencreat.domain.im.vo.OpenIMResultVo;
import com.tencreat.domain.im.vo.OpenIMTokenVo;
import com.tencreat.domain.mall.vo.MallStoreGoodsVO;
import com.tencreat.service.account.*;
import com.tencreat.service.account.impl.MallStoreServiceImpl;
import com.tencreat.service.im.IImCustomerService;
import com.tencreat.service.mall.IAppDownloadRecordService;
import com.tencreat.service.mall.IMallOrderGoodsService;
import com.tencreat.service.mall.IMallOrderService;
import com.tencreat.service.mall.IRechargeLimitChangeService;
import com.tencreat.service.system.ISysMessageService;
import com.tencreat.service.system.ISysStudentService;
import com.tencreat.service.system.impl.SysUserServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

import static com.baomidou.mybatisplus.core.toolkit.Wrappers.lambdaUpdate;

/**
 * @author tang jun liang
 * @version 1.0
 * @date 2021/9/6 10:46
 */
@Api(tags = "93-用户开放接口")
@RequestMapping("/api/account/open")
@RestController
@Slf4j
@RequiredArgsConstructor
public class AccountOpenController extends BaseController {

    private final IAccountLoginCheckService accountLoginCheckService;
    private final ICommonRichTextService commonRichTextService;
    private final IMallUserService mallUserService;
    private final IMallRegionService mallRegionService;
    private final IMallSupplierService supplierService;
    private final IMallStoreService mallStoreService;
    private final ISysMessageService sysMessageService;
    private final IAppVersionService appVersionService;
    private final IAppDownloadRecordService appDownloadRecordService;
    private final IMallOrderGoodsService mallOrderGoodsService;
    private final IRechargeLimitChangeService rechargeLimitChangeService;
    private final IMallOrderService mallOrderService;
    private final SysUserServiceImpl sysUserService;
    private final IImCustomerService imCustomerService;

    @ApiOperation(value = "统一登录接口")
    @PostMapping("/login")
    public HttpResult<ResAccountLogin> login(@RequestBody AccountLoginDTO accountLoginPo) {
        return accountLoginCheckService.login(accountLoginPo);
    }

    @ApiOperation(value = "IM客服登录")
    @PostMapping("/loginIMCustomer")
    HttpResult<OpenIMTokenVo> loginIMCustomer(@RequestBody ImCustomer imCustomer) {
        OpenIMResultVo<OpenIMTokenVo> tokenResult = imCustomerService.loginIMCustomer(imCustomer);
        return HttpResult.ok(tokenResult.getData());

      /*  ImCustomer one = imCustomerService.lambdaQuery().eq(ImCustomer::getUsername, imCustomer.getUsername())
                .eq(ImCustomer::getPassword, imCustomer.getPassword())
                .one();
        if (null != one) {
            if (one.getStatus() != 0) {
                throw new CustomException("客服被禁用");
            }
            // 登录成功
            OpenIMResultVo<OpenIMTokenVo> result = imCustomerService.loginIM(new OpenIMLoginDTO(10), getUuid());
            if(result.getErrCode() == 0){
                OpenIMTokenVo data = result.getData();
                // 获取后台登录token
                LoginUserIM loginUserIM = new LoginUserIM();
                BeanUtils.copyBeanProp(loginUserIM, one);
                LoginUser loginUser = new LoginUser(loginUserIM);
                String loginToken = tokenService.createToken(loginUser);
                data.setLoginToken(loginToken);
                return HttpResult.ok(data);
            }
            return HttpResult.error("登录IM账号失败，请重试");
        } else {
            return HttpResult.error("账号或密码错误");
        }*/
    }

    @ApiOperation(value = "OpenIM登录接口,获取token")
    @PostMapping("/loginIMUser")
    public HttpResult<OpenIMTokenVo> loginIMUser(@RequestBody OpenIMLoginDTO openIMLoginDTO) {
        OpenIMResultVo<OpenIMTokenVo> tokenResult = imCustomerService.loginIM(openIMLoginDTO, getUuid());
        return HttpResult.ok(tokenResult.getData());
    }

    @ApiOperation(value = "个人信息")
    @PostMapping("/info")
    public HttpResult<ResOpenUserInfoVO> login() {
        return mallUserService.info(getLoginCheck());
    }

    @ApiOperation(value = "统一注册接口")
    @PostMapping("/register")
    @RepeatSubmit
    public HttpResult<String> register(@Validated @RequestBody AccountRegisterDTO accountRegisterPo) {
        HttpResult result = accountLoginCheckService.register(accountRegisterPo);

//		MallUser mallUser = mallUserService.lambdaQuery().eq(MallUser::getMobile, accountRegisterPo.getPhone()).one();
//		rechargeLimitChangeService.change(mallUser);

        log.info("注册结束{}", DateUtil.now());
        return result;
    }

    /**
     *
     * @Author wangbingcheng
     * @Date 2021年09月10日
     * @param openSendCodePO
     * @Return
     */
    @ApiOperation(value = "发送验证码")
    @PostMapping("/send_code_admin")
    public HttpResult<Void> sendCodeAdmin(@RequestBody ShopOpenSendCodeDTO openSendCodePO) {
        sysMessageService.sendSMS(openSendCodePO);
        return HttpResult.ok();
    }


    @ApiOperation(value = "供应商入驻申请")
    @PostMapping("/supplier_settle_in")
    @RepeatSubmit
    public HttpResult<String> supplierSettleIn(@RequestBody @Validated AccountOpenSupplierSettleInDTO dto) {
        Long uuid = SecurityUtils.getLoginUser().getAccountLogin().getUuid();
        int count = supplierService.lambdaQuery().eq(MallSupplier::getUuid, uuid).count();
        if (count > 0) {
            return HttpResult.error("你已申请过供应商请勿重复申请");
        }
        MallSupplier mallSupplier = CglibUtil.copy(dto, MallSupplier.class);
        mallSupplier.setUuid(uuid);
        mallSupplier.setApprovalStatus(AllEnum.SupplierGoods.YES.getType());
        mallSupplier.setStatus(AllEnum.EventEnum.YES.getType());
        mallSupplier.setCreateTime(LocalDateTime.now());

        MallUser one = mallUserService.lambdaQuery().eq(MallUser::getUuid, uuid).one();
        one.setSupplier(Long.valueOf(AllEnum.SupplierGoods.YES.getType()));
        mallUserService.updateMallUser(one);


        // 创建用户密码
        String password = RandomUtil.randomString(6);
        // 创建一个后台账号
        SysUser user = supplierService.insertSysUser(mallSupplier, password);

        mallSupplier.setUserId(user.getUserId());
        mallSupplier.setAccount(user.getUserName());
        supplierService.save(mallSupplier);
//		wrapper.update();
        // 发送信息
        sysMessageService.smsSupplierApproved(user.getPhonenumber(), user.getUserName(), password);
        return HttpResult.ok();
    }

    @ApiOperation(value = "供应商入驻状态")
    @PostMapping("/supplierSettleInStatus")
    public HttpResult<Long> supplierSettleInStatus() {
        Long uuid = SecurityUtils.getLoginUser().getAccountLogin().getUuid();
        return HttpResult.ok(supplierService.selectApprovalStatus(uuid));
    }

    @ApiOperation(value = "店铺入驻申请")
    @PostMapping("/store_settle_in")
    @RepeatSubmit
    public HttpResult<String> storeSettleIn(@RequestBody @Validated AccountOpenStoreSettleInDTO dto) {
        // 经纬度必传
        if (StringUtils.isEmpty(dto.getLongitude()) || StringUtils.isEmpty(dto.getDimensionality())) {
            return HttpResult.error("请授权定位或重新选择位置");
        }
        Long uuid = getUuid();
        int count = mallStoreService.lambdaQuery().eq(MallStore::getUuid, uuid)
                .eq(MallStore::getApprovalStatus, 0)
                .eq(MallStore::getMobile, dto.getMobile())
                .count();
        int count2 = mallStoreService.lambdaQuery().eq(MallStore::getUuid, uuid)
                .eq(MallStore::getApprovalStatus, 1)
                .eq(MallStore::getMobile, dto.getMobile())
                .count();
        if (count > 0 || count2 > 0) {
            return HttpResult.error("你已申请过店铺请勿重复申请");
        }

        MallStore mallStore = CglibUtil.copy(dto, MallStore.class);
        mallStore.setUuid(uuid);
//		mallStore.setClassify(dto.getType());
        //将审核状态设置为审核成功
        mallStore.setApprovalStatus(AllEnum.StoreGoods.YES.getType());
        mallStore.setStatus(AllEnum.EventEnum.YES.getType());
        mallStore.setCreateTime(LocalDateTime.now());
        mallStore.setBusinessStartHours(dto.getBusinessStartTime());
        mallStore.setBusinessEndHours(dto.getBusinessEndTime());
//		mallStoreService.save(mallStore);

        MallUser one = mallUserService.lambdaQuery().eq(MallUser::getUuid, uuid).one();
        one.setStore((long) AllEnum.StoreGoods.YES.getType());
        mallUserService.updateMallUser(one);

        // 创建用户密码
        String password = RandomUtil.randomString(6);
        // 创建一个后台账号
        SysUser user = mallStoreService.insertSysUser(mallStore, password);

        mallStore.setUserId(user.getUserId());
        mallStore.setAccount(user.getUserName());
        mallStoreService.save(mallStore);
//		wrapper.update();
        // 发送信息
        sysMessageService.smsStoreApproved(user.getPhonenumber(), user.getUserName(), password);
        return HttpResult.ok();

    }

    @ApiOperation(value = "店铺入驻状态")
    @PostMapping("/storeSettleInStatus")
    public HttpResult<Long> storeSettleInStatus() {
        Long uuid = SecurityUtils.getLoginUser().getAccountLogin().getUuid();
        return HttpResult.ok(mallStoreService.selectStoreApprovalStatus(uuid));
    }

    @ApiOperation(value = "修改头像")
    @PostMapping("/updateAvatar")
    public HttpResult<String> updateAvatar(@RequestBody MallUser mallUser) {
        mallUserService.lambdaUpdate().eq(MallUser::getUuid, getLoginCheck().getAccountLogin().getUuid())
                .set(MallUser::getAvatar, mallUser.getAvatar())
                .update();

        return HttpResult.ok();
    }


    @ApiOperation(value = "修改昵称")
    @PostMapping("/updateNickName")
    public HttpResult<String> updateNickName(@RequestBody MallUser mallUser) {
        mallUserService.lambdaUpdate().eq(MallUser::getUuid, getLoginCheck().getAccountLogin().getUuid())
                .set(MallUser::getNickname, mallUser.getNickname())
                .update();

        return HttpResult.ok();
    }

    @ApiOperation(value = "忘记密码")
    @PostMapping("/forget_password")
    public HttpResult<String> forgetPassword(@RequestBody AccountPhoneAndCodeDTO accountPhoneAndCodePO) {
        return accountLoginCheckService.forgetPassword(accountPhoneAndCodePO);
    }

    @ApiOperation(value = "修改密码")
    @PostMapping("/update_password")
    public HttpResult<String> updatePassword(@RequestBody AccountPhoneAndCodeDTO accountPhoneAndCodePO) {
        return accountLoginCheckService.updatePassword(accountPhoneAndCodePO);
    }

    @ApiOperation(value = "用户协议")
    @GetMapping("/agreement")
    public HttpResult<CommonRichText> agreementByType(@RequestParam String type) {
        return commonRichTextService.selectInfoByType(type);
    }

    @ApiOperation(value = "重新设置支付密码")
    @GetMapping("/pay_password")
    public HttpResult<Boolean> payPassword(@RequestParam String payPassWord) {
        return mallUserService.payPassword(payPassWord, getLoginCheck());
    }

    @ApiOperation(value = "退出登录")
    @GetMapping("/sign_out")
    public HttpResult<String> signOut() {
        return mallUserService.signOut(getLoginCheck());
    }

    @ApiOperation(value = "检验旧手机号修改手机")
    @PostMapping("/chick_phone")
    public HttpResult<String> chickPhone(@RequestBody CodeAndType codeAndType) {
        return accountLoginCheckService.chickPhone(codeAndType, getLoginCheck());
    }

    @ApiOperation(value = "更改新手机号")
    @PostMapping("/update-new-phone")
    public HttpResult<String> updateNewPhone(@RequestBody @Validated UpdateNewPhoneDTO updateNewPhoneDTO) {
        CodeAndType codeAndType = new CodeAndType();
        codeAndType.setCode(updateNewPhoneDTO.getCode());
        codeAndType.setType(CitySmsTypeEnum.CHECK_NEW_PHONE.getType());
        codeAndType.setPhone(updateNewPhoneDTO.getNewPhone());
        List<MallUser> list = mallUserService.lambdaQuery().eq(MallUser::getMobile, updateNewPhoneDTO.getNewPhone()).list();
        if (list.size() > 0) {
            return HttpResult.error("手机号已存在");
        }
        HttpResult result = accountLoginCheckService.chickPhone(codeAndType, getLoginCheck());
        if (result.getCode() == HttpStatus.ERROR) {
            return result;
        }
        accountLoginCheckService.changePhone(updateNewPhoneDTO);
        return HttpResult.ok();
    }

    /**
     * 查询省
     */
    @ApiOperation(value = "查询省")
    @PostMapping("/province")
    public HttpResult<List<TencreatIdAndName>> getProvincelist() {
        return mallRegionService.getProvince();
    }


    /**
     * 查询省
     */
    @ApiOperation(value = "查询市或区")
    @PostMapping("/city_county")
    public HttpResult<List<TencreatIdAndName>> getCityAndCountyList(@RequestBody ReqIdParam reqIdParam) {
        return mallRegionService.getCityAndCounty(reqIdParam);
    }

    /**
     * 系统版本
     */
    @ApiOperation(value = "系统版本")
    @PostMapping(value = "/version")
    public HttpResult<AppVersion> version() {
        AppVersion one = appVersionService.lambdaQuery()
                .eq(AppVersion::getDelFlag, 0)
                .orderByDesc(AppVersion::getVersionCode)
                .last("limit 1").one();
        return HttpResult.ok(one);
    }

    @ApiOperation(value = "APP端查询我的团队")
    @PostMapping("/appSelectTeam")
    public HttpResult<AppMyTeamInfoVO> appSelectTeam() {
        return HttpResult.ok(mallUserService.appSelectTeam(getLoginCheck()));
    }

    @ApiOperation(value = "APP端查询我的团队--带分页")
    @PostMapping("/appSelectOneTeam")
    HttpResult<Page<AccountMyTeamVo>> appSelectOneTeam(@RequestBody ReqPageParam param) {
//        Page<AppMyTeamInfoVO> page = new Page<>(param.getPageNum(), param.getPageSize());
        return HttpResult.ok(mallUserService.appSelectOneTeam(param,getUuid()));
    }

    /**
     * 新增app下载记录
     */
    @ApiOperation(value = "新增app下载记录")
    @Log(title = "app下载记录", businessType = BusinessType.INSERT)
    @PostMapping(value = "/appDownloadRecord/add")
    public HttpResult<Boolean> add(@RequestBody @Validated AppDownloadRecord appDownloadRecord) {
        appDownloadRecord.setCreateTime(LocalDateTime.now());
        return to(appDownloadRecordService.save(appDownloadRecord));
    }

    @ApiOperation(value = "注销")
    @GetMapping("/logOff")
    public HttpResult<Boolean> logOff() {
        Long uuid = getLoginCheck().getAccountLogin().getUuid();
        // 查询是否有未完成的订单
        Integer count = mallOrderGoodsService.lambdaQuery().eq(MallOrderGoods::getUuid, uuid)
                .in(MallOrderGoods::getOrderStatus, OrderStatus.WAIT_DELIVER, OrderStatus.WAIT_RECEIVED, OrderStatus.WAIT_USE).count();
        if (count > 0) {
            throw new CustomException("存在未完成的订单");
        }
        boolean rows = mallUserService.lambdaUpdate().eq(MallUser::getUuid, uuid)
                .set(MallUser::getDelFlag, "2")
                .set(MallUser::getUsername, System.currentTimeMillis())
                .set(MallUser::getUpdateTime, LocalDateTime.now())
                .update();
        accountLoginCheckService.lambdaUpdate().eq(AccountLoginCheck::getUuid, uuid)
                .set(AccountLoginCheck::getDelFlag, "2")
                .set(AccountLoginCheck::getUpdateTime, LocalDateTime.now())
                .update();
        if (rows) {
            mallUserService.signOut(getLoginCheck());
        }

        return HttpResult.ok(rows);
    }

    @ApiOperation("实名认证")
    @PostMapping("/verify")
    HttpResult<Boolean> list(@RequestBody MallUser mallUser) {
        Long uuid = SecurityUtils.getLoginUser().getAccountLogin().getUuid();
        // 实名认证
        boolean verify = true;
        // 身份二要素验证
        verify = VerifyUtil.verify(mallUser.getIdCard(), mallUser.getRealName(), uuid);
        if (!verify) {
            throw new CustomException("实名认证信息错误,请填写正确");
        }
        // 修改用户信息
        return HttpResult.ok(mallUserService.lambdaUpdate()
                .eq(MallUser::getUuid, uuid)
                .set(MallUser::getRealName, mallUser.getRealName())
                .set(MallUser::getIdCard, mallUser.getIdCard())
                .set(MallUser::getRealStatus, 1)
                .update());
    }


    @ApiOperation(value = "获取订单数")
    @PostMapping(value = "/appGetIndexNum")
    public HttpResult<MallOrderStatisticsVO> getInfo(@RequestBody MallOrder mallOrder) {
        MallUser one = mallUserService.lambdaQuery().eq(MallUser::getUuid, getUuid()).one();
        SysUser sysUser = sysUserService.selectUserByPhone(one.getMobile(), mallOrder.getUserType());
        mallOrder.setUserId(sysUser.getUserId());
        return mallOrderService.getInfo(mallOrder);
    }

    @ApiOperation("昵称改变")
    //@PostMapping("/change")
    public void change() {
        List<MallUser> list = mallUserService.list();
        for (MallUser mallUser : list) {
            if (mallUser.getMobile().length() < 11) {
                continue;
            }
            String first = mallUser.getMobile().substring(0, 3);
            String end = mallUser.getMobile().substring(mallUser.getMobile().length() - 4);
            String nickName = first + "****" + end;
            mallUser.setNickname(nickName);
            mallUserService.updateById(mallUser);
        }

    }

}
